const got = require("got");

const CONTENTYPE = {
    json: "application/json",
    uri: "application/x-www-form-urlencoded"
};

module.exports = function (context, ops) {
    let cancel = null, _request = null;
    let promise = new Promise((resolve, reject) => {
        cancel = reject;
        let url = ops.url;
        if (url.indexOf("http") !== 0) {
            if (url[0] === "/") {
                let location = context.window.location;
                url = location.origin + url.replace(/[\/]+/g, "/");
            } else {
                url = context.window.location.href.replace(/[\/]+/g, "/") + "/" + url.replace(/[\/]+/g, "/");
            }
        }
        let option = {
            method: ops.method,
            headers: Object.assign(ops.headers, {
                "Origin": context.window.location.origin,
                "X-Requested-With": "XMLHttpRequest",
                "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"
            }),
            cookieJar: context._cookie,
            timeout: ops.timeout
        };
        if (ops.method === "get") {
            option.searchParams = ops.data;
        } else {
            if (ops.contentType !== false) {
                option.headers["Content-type"] = CONTENTYPE[ops.contentType] || ops.contentType;
            }
            if (ops.contentType === 'json') {
                ops.json = true;
            }
            option.body = ops.data;
        }
        _request = got(url, option).then(response => {
            _request = null;
            let status = response.statusCode;
            if ((status >= 200 && status < 300) || status === 304 || status === 0) {
                return {
                    data: response.body,
                    status,
                    statusText: response.body,
                    data: response.body,
                    headers: response.headers,
                    option: ops
                };
            } else {
                return {
                    status,
                    headers: response.headers,
                    option: ops,
                    error
                };
            }
        }).catch(error => {
            console.log(error);
            _request = null;
            return {
                status: 500,
                option: ops,
                error
            };
        }).then(a => resolve(a));
    });
    return {
        promise, cancel: () => {
            if (_request) {
                _request.cancel();
                _request = null;
                cancel(`[ada] request abort`);
            }
        }
    }
};